/* Copyright © Worklight Ltd. 2006-2011.  All rights reserved. */

package com.worklight.wlclient.api;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;

import com.worklight.wlclient.WLClientUtils;
import com.worklight.wlclient.api.WLErrorCode;

/**
 * Extends WLResponse, contains errorCode codes and messages, 
 * in addition to the status in WLResponse. 
 * Contains the original response data object from the server as well.
 */
public class WLFailResponse extends WLResponse {
	
	private static final String JSON_KEY_ERROR_MSG  = "errorMsg";
	private static final String JSON_KEY_ERROR_CODE = "errorCode";
	
	protected WLErrorCode errorCode;
	protected String errorMsg;

	public WLFailResponse(HttpResponse httpResponse) {
		super(httpResponse);
		parseErrorFromResponse();
	}
	
	public WLFailResponse(WLResponse wlResponse) {
		super(wlResponse);
		parseErrorFromResponse();
	}

	public WLFailResponse(WLErrorCode errorCode, String errorMsg, WLRequestOptions requestOptions) {
		super(HttpStatus.SC_INTERNAL_SERVER_ERROR, "", requestOptions);		
		setErrorCode(errorCode);
		setErrorMsg(errorMsg);		
	}
	
	/**
	 * @return possible errors define in {@link WLErrorCode}
	 */
	public WLErrorCode getErrorCode() {
		return errorCode;
	}
	
	public void setErrorCode(WLErrorCode errorCode) {
		this.errorCode = errorCode;
	}

	/**
	 * @return A developer oriented errorCode message - no necessarily suitable to display for the user.
	 */
	public String getErrorMsg() {
		if (errorMsg == null){
			return errorCode.getDescription();
		}
		return errorMsg;
	}
	
	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
		
	private void parseErrorFromResponse() {
		if (getResponseText() != null && getResponseText().length() > 0) {
			try {
				JSONObject jsonResponse = WLClientUtils.convertStringToJSON (this.getResponseText());
				
				errorCode = WLErrorCode.UNEXPECTED_ERROR;
				if (jsonResponse.has(JSON_KEY_ERROR_CODE)) {
					// Handle failure of the procedure invocation
					errorCode = WLErrorCode.valueOf(jsonResponse.getString(JSON_KEY_ERROR_CODE));
				};
				
				if (jsonResponse.has(JSON_KEY_ERROR_MSG)) {
					errorMsg = jsonResponse.getString(JSON_KEY_ERROR_MSG);
				} 
			}
			catch (JSONException e) {
				WLClientUtils.error(String.format("Cannot retrieve errorCode message from response. Response text is:%s'",this.getResponseText()), e);
				errorCode = WLErrorCode.UNEXPECTED_ERROR;
				if (getStatus() >= HttpStatus.SC_INTERNAL_SERVER_ERROR) {
					errorCode = WLErrorCode.UNRESPONSIVE_HOST;
				} else if (getStatus() >= HttpStatus.SC_REQUEST_TIMEOUT) {
					errorCode = WLErrorCode.REQUEST_TIMEOUT;
				} 
			}
		}
	}
	
	@Override
	public String toString() {
		return super.toString() + 
			" WLFailResponse [errorMsg=" + errorMsg + 
			", errorCode=" + errorCode + "]";
	}
}
